package com.quanyan.ic.vendingMachine.http.interceptor;

import com.alibaba.fastjson.JSON;
import com.quanyan.ic.common.spring.SpringUtil;
import com.quanyan.ic.vendingMachine.model.OrderItem;
import com.quanyan.ic.vendingMachine.model.OrderPaySuccessResult;
import com.quanyan.ic.vendingMachine.protocol.Cmd;
import com.quanyan.ic.vendingMachine.protocol.codec.protobuf.VmMessageBuilder;
import com.quanyan.ic.vendingMachine.protocol.codec.protobuf.VmMessageProto;
import com.quanyan.ic.vendingMachine.protocol.server.session.Session;
import com.quanyan.ic.vendingMachine.protocol.server.session.SessionManager;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by zhuo.shi on 2017/8/2.
 * 订单支付成功后，收到回调，向客户端下发出货命令
 */
@Aspect
@Component
public class OrderPaySuccessInterceptor {

    private Logger logger = LoggerFactory.getLogger(OrderPaySuccessInterceptor.class);

    @Pointcut("execution(* com.quanyan.ic.vendingMachine.http.service.VmOrderService.processOrderPayCallback(..))")
    public void orderPaySuccess() {
    }

    @Around(value = "orderPaySuccess()")
    public Object sendShipGoodsNotify(ProceedingJoinPoint poj) throws Throwable {
        try {
            Object result = poj.proceed();
            logger.info("---> method [{}] is called, return {}", poj.getSignature().getName(), result == null ? "null" : JSON.toJSONString(result));
            if (result != null) {
                OrderPaySuccessResult orderPaySuccessResult = (OrderPaySuccessResult) result;
                sendShipGoodsCmd(orderPaySuccessResult);
            }
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
    }

    /**
     * 向客户的发送出货命令
     */
    private void sendShipGoodsCmd(OrderPaySuccessResult result) {
        final String vmNumber = result.getVmNumber();
        SessionManager sessionManager = SpringUtil.getBean("sessionManager", SessionManager.class);
        Session session = sessionManager.get(vmNumber);
        if (session == null || session.getChannel() == null) {
            logger.warn("---> send cmd [{}] to vm [{}], client offline", Cmd.ORDER_SUCCESS.getDesc(), vmNumber);
            return;
        }
        List<VmMessageProto.VmMessage.OrderSuccess> osList = new ArrayList<>();
        for (OrderItem orderItem : result.getOrderItemList()) {
            VmMessageProto.VmMessage.OrderSuccess.Builder b = VmMessageProto.VmMessage.OrderSuccess.newBuilder();
            b.setOrderNo(orderItem.getOrderNo());
            b.setGoodsId(orderItem.getGoodsInfo().getId());
            b.setGrid(orderItem.getGrid());
            b.setGridNumber(orderItem.getGridNumber());
            b.setQty(orderItem.getQty());
            osList.add(b.build());
        }
        Channel channel = session.getChannel();
        final VmMessageProto.VmMessage msg = new VmMessageBuilder(vmNumber)
                .buildCmd(Cmd.ORDER_SUCCESS)
                .buildOrderSuccessList(osList).getMessage();
        ChannelFuture f = channel.writeAndFlush(
                msg
        );
        f.addListener(new ChannelFutureListener() {
            @Override
            public void operationComplete(ChannelFuture channelFuture) throws Exception {
                logger.info("---> send cmd [{}] to vm [{}] completed, d={} c={} s={}, msg=\n{}",
                        Cmd.ORDER_SUCCESS.getDesc(), vmNumber, channelFuture.isDone(), channelFuture.isCancelled(), channelFuture.isSuccess(), msg);
            }
        });
    }
}
